package net.deiangi.graphs.ui;

import net.deiangi.graphs.MyGraphApplet;
import net.deiangi.graphs.core.Graph;
import net.deiangi.graphs.core.Node;

import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;

/**
 * User: Deian
 * Date: Oct 31, 2009
 * Time: 12:03:46 AM
 */
public class GraphPanel extends Panel implements Runnable, MouseListener, MouseMotionListener {
    private MyGraphApplet parent;
    private Graph graph;
    public GraphRenderer graphRenderer;
    private Node pick;

    public GraphPanel(MyGraphApplet parent) {
        this.parent = parent;
        graph = new Graph();
        graphRenderer = new GraphRenderer(this, graph);
        addMouseListener(this);
    }

    Thread relaxer;

    public void start() {
        relaxer = new Thread(this);
        relaxer.start();
    }

    public void stop() {
        relaxer = null;
    }

    @Override
    public void update(Graphics g) {
        graphRenderer.update(g);
    }

    public void run() {
        for (; ;) {
            graphRenderer.relax();
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                break;
            }
        }
    }

    //1.1 event handling
    public void mouseClicked(MouseEvent e) {
        if (e.getButton() == MouseEvent.BUTTON1) {
            if (e.getClickCount() >= 2) {
                int x = e.getX();
                int y = e.getY();
                Node fixNode = null;
                double bestdist = Double.MAX_VALUE;
                for (Node n : graph.nodes) {
                    double dist = (n.x - x) * (n.x - x) + (n.y - y) * (n.y - y);
                    if (dist < bestdist) {
                        fixNode = n;
                        bestdist = dist;
                    }
                }
                fixNode.fixed = !fixNode.fixed;
            }
        }
    }

    public void mousePressed(MouseEvent e) {
        addMouseMotionListener(this);
        double bestdist = Double.MAX_VALUE;
        int x = e.getX();
        int y = e.getY();
        for (Node n : graph.nodes) {
            double dist = (n.x - x) * (n.x - x) + (n.y - y) * (n.y - y);
            if (dist < bestdist) {
                pick = n;
                bestdist = dist;
            }
        }
        pick.selected = true;
        pick.x = x;
        pick.y = y;
        repaint();
        e.consume();
    }

    public void mouseReleased(MouseEvent e) {
        removeMouseMotionListener(this);
        if (pick != null) {
            pick.x = e.getX();
            pick.y = e.getY();
            pick.selected = false;
            pick = null;
        }
        repaint();
        e.consume();
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseDragged(MouseEvent e) {
        pick.x = e.getX();
        pick.y = e.getY();
        repaint();
        e.consume();
    }

    public void mouseMoved(MouseEvent e) {
    }


    public void reload(String text) {
        graph.clear();
        graph.load(text);
        graph.randomize(getSize());
    }
}
